package com.ultra.template.parse;

import com.ultra.exception.UnableResolveTypeException;
import com.ultra.reflect.ReflectUtil;
import com.ultra.template.content.AcvContext;
import com.ultra.template.content.Argument;
import com.ultra.template.content.Pairs;

import java.lang.reflect.*;
import java.util.*;

import com.ultra.exception.UnknownTypeException;
import org.jetbrains.annotations.NotNull;
import sun.misc.Unsafe;

/**
 * @author yinger
 * @description
 * @date 2024/12/30
 **/
public final class Parser {
    // 下标为深度 值为 k
    public static int[] times = new int[9];// 最大深度 9
    public static Map<Pairs, Argument> flatteningMap = new HashMap();

    /**
     * 一次性生产 n 组测试样本 2 ≤ n ≤ 10 (安全机制) -> 扩展项
     *
     * @throws com.ultra.exception.UnknownTypeException 未知类型异常
     * @throws UnableResolveTypeException               无法解析类型异常
     * @throws ClassNotFoundException                   类未找到异常
     * @throws InvocationTargetException                调用目标异常
     * @throws NoSuchMethodException                    无此类方法异常
     * @throws InstantiationException                   实例化异常
     * @throws IllegalAccessException                   访问权限异常
     */
    public static void parserDispatcher(Argument argument)
            throws UnknownTypeException,
            ClassNotFoundException,
            InvocationTargetException,
            NoSuchMethodException,
            InstantiationException,
            IllegalAccessException, UnableResolveTypeException {
        Type type = argument.getType();
        if ("org.ultra.validator.common.util.ListNode".equals(type.getTypeName())) {
            GenericCollectionParser._fromCollection(argument);
        } else {
            if (type instanceof Class<?>) {
                if (((Class<?>) type).getComponentType() != null) {
//            if (((Class<?>) type).isArray()) {
                    // int[]
                    ArrayParser._fromArray(argument);
                } else {
                    // int or Integer  -> leaf
                    if (((Class<?>) type).getName().equals("java.lang.String")) {
                        // TODO 待解决 ？
                        BasicParser._fromCollection(argument);
                    } else {
                        BasicParser.createLeafObject(argument);
                    }
                }
            } else if (type instanceof ParameterizedType) {
                // List<Integer>
                Class<?> clazz = Class.forName(((ParameterizedType) type).getRawType().getTypeName());
                if (Collection.class.isAssignableFrom(clazz)) {
                    // Collection 接口
                    GenericCollectionParser._fromCollection(argument);
                } else if (Map.class.isAssignableFrom(clazz)) {
                    // Map 接口
                    MapParser._fromMap(argument);
                } else {
                    // 自定义泛型集合
                    // 反射 id & value 字段
                }
            } else if (type instanceof GenericArrayType) {
                // List<Integer>[]
                GenericArrayParser._fromGenericArray(argument);
            } else if (type instanceof TypeVariable<?>) {
                // List<T>
                throw new UnableResolveTypeException("TypeVariable");
            } else if (type instanceof WildcardType) {
                // List<?>
                throw new UnableResolveTypeException("WildcardType");
            } else {
                // ...
                throw new UnknownTypeException("UnknownType " + type);
            }
        }

    }

    /**
     * 预处理参数
     *
     * @throws UnableResolveTypeException 无法解析类型异常
     * @throws UnknownTypeException       未知类型异常
     * @throws ClassNotFoundException     类未找到异常
     * @throws InvocationTargetException  调用目标异常
     * @throws NoSuchMethodException      无此类方法异常
     */
    public static List<Argument> parseMethodSignature() throws
            UnableResolveTypeException,
            UnknownTypeException,
            ClassNotFoundException,
            InvocationTargetException,
            NoSuchMethodException,
            InstantiationException,
            IllegalAccessException {
        AcvContext.clazz = ReflectUtil.scanValidatorAnnotation("com.ultra.validator");
        Method method = ReflectUtil.reflectValidatorAnnotationMethod();
        assert method != null;
        Type[] types = method.getGenericParameterTypes();
        List<Argument> arguments = new ArrayList<>();

        for (int i = 0; i < types.length; i++) {
            arguments.add(new Argument());
            // 当前为第 i 个参数
            arguments.get(i).setIThArgument(i);
            // 第一层深度为 0
            arguments.get(i).setDepth(0);
            arguments.get(i).setType(types[i]);
        }

        for (int i = 0; i < types.length; i++) {
            Arrays.fill(times, 0);
            parserDispatcher(arguments.get(i));
        }
        return arguments;
    }
}